home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdCmd2.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
16KB
|
635 lines
(*************************************************************************
:Program. EdCmd2.mod
:Contents. Commands for AmokEd
:Author. Hartmut Goebel
:Language. Oberon
:Translator. Amiga Oberon Compiler V2.00
:Imports. SupLib (Hartmut Goebel)
:History. V0.1, 23 Mar 1991 Hartmut Goebel
:History. V1.0, 14 Apr 1991 Hartmut Goebel [hG]
:History. V1.0b 28 Apr 1991 [hG] changed doNewWindow <- edL.TextInit
:History. V1.0c 06 Jun 1991 [hG] +Vars lineno, colno
:History. V1.1 12 Jun 1991 [hG] Scanf complited (SScanf v. V.Rudolph)
:History. V1.1b 17 Jun 1991 [hG] eigener Screen möglich
:Date. 18 Oct 1991 21:36:31
*************************************************************************)
MODULE EdCmd2;
(* $Debug- *)
IMPORT
cv: Conversions,
d: Dos,
e: Exec,
edD: EdDisplay,
edE: EdErrors,
edG: EdGlobalVars,
edK: EdKeyboard,
edL: EdLowLevel,
eGd: EdGadgets,
eMn: EdMenu,
g: Graphics,
I: Intuition,
lst: EdLists,
ol: OberonLib,
sl: SupLib,
str: Strings,
sys: SYSTEM;
TYPE
Variable = STRUCT (node: lst.Node)
name: edG.StringPtr;
string: edG.StringPtr;
END;
VarPtr = POINTER TO Variable;
(* WICHTIG: Bei Änderungen Offsets in FindReplace.asm überprüfen!! *)
FindReplaceStruct = STRUCT
findStr: edG.StringPtr;
line: edG.LinePtr;
flen: INTEGER;
pos: INTEGER;
END;
CONST
(* Flags für einzelne Kommandos *)
replace*=0;
previous*=1;
oldStrings*=2;
top*=0;
height*=1;
temp*=2;
leftEdge*={top,height};
ReplaceQuestion = "Replace? (y/n/a/q)";
NoFindPattern = "No find pattern";
NoReplacePattern = "No replace pattern";
PatternNotFound = "Pattern Not Found";
ReplaceLineTooLong = "Replace: Line Too Long";
WindowTooBig = "window too big (try moving to upper left corner and retrying)";
ExecuteFailed = "Execute failed!";
VAR
VarList: lst.List;
VarBuffer: ARRAY 14 OF CHAR;
(*-----------------------------------------------------------------------*)
PROCEDURE doUndo*;
BEGIN
edD.TextLoad;
edD.TextRedisplayCurrentLine;
END doUndo;
PROCEDURE doNull*; (* macht absolut nichts *)
BEGIN END doNull;
PROCEDURE doAbort*; (* subject of change *)
BEGIN
edG.Rc := edE.AbortLevel;
END doAbort;
PROCEDURE doVersion*;
BEGIN
edL.Title(edG.Version); edG.Rc := edE.cmdValid2;
END doVersion;
(*-----------------------------------------------------------------------*)
PROCEDURE doTLate*;
VAR
ch: CHAR;
long: LONGINT;
BEGIN
IF NOT edL.StrToInt(edG.Arg[0],long) OR (long > 255) THEN
edG.Rc := edE.cmdError; edL.Title(edG.BadArgument);
RETURN;
END;
ch := edG.LineBuffer[edG.Text.pos];
IF ch = 0X THEN
ch := 20X; END;
IF edG.Arg[0][0] < "0" THEN (* mit Vorzeichen => relativ *)
ch := CHR(ORD(edG.LineBuffer[edG.Text.pos])+long);
ELSE
ch := CHR(long);
END;
IF ch # 0X THEN
IF edG.LineBuffer[edG.Text.pos] = 0X THEN (* letztes Zeichen *)
INC(edG.LineBufferLen);
edG.LineBuffer[edG.LineBufferLen] := 0X;
END;
edG.LineBuffer[edG.Text.pos] := ch;
IF NOT (edG.NoScreenUpdate > 0) THEN
edL.MoveToCursor;
edD.SetPen(edG.Text.line);
edG.Arg[1] := sys.ADR(edG.LineBuffer[edG.Text.pos]);
g.Text(edG.RPort,edG.Arg[1]^,1);
END;
END;
END doTLate;
(*-----------------------------------------------------------------------*)
PROCEDURE doScanf*;
CONST
StrLen = 80;
VAR
i,j:INTEGER;
maxWidth:INTEGER;
allAllowed:BOOLEAN;
negAllowed:BOOLEAN;
allowedChars:ARRAY StrLen OF CHAR;
fmtLen:INTEGER;
argLen:INTEGER;
argStr: edG.StringPtr;
PROCEDURE IsAllowed(ch:CHAR):BOOLEAN;
VAR
i:INTEGER;
BEGIN
IF ch = ' ' THEN RETURN FALSE END;
IF allAllowed THEN RETURN TRUE END;
i := 0;
WHILE (allowedChars[i] # ch) AND
(allowedChars[i] # 0X) DO
INC(i);
END; (* WHILE *)
IF allowedChars[i] = 0X THEN
RETURN negAllowed
ELSE
RETURN NOT negAllowed;
END;(* IF *)
END IsAllowed;
PROCEDURE BadArgument;
BEGIN
edG.Rc := edE.cmdError; edL.Title(edG.BadArgument);
END BadArgument;
BEGIN
i := 0;
argStr := sys.ADR(edG.LineBuffer[edG.Text.pos]);
fmtLen := str.Length(edG.Arg[0]^);
argLen := str.Length(argStr^);;
DISPOSE(edG.ScanStr);
(* scan format string *)
(* skip leading garbage *)
i := 0;
WHILE (i < fmtLen) AND (edG.Arg[0][i] # '%') DO
INC(i); END;
IF i = fmtLen THEN
BadArgument; RETURN;
END;
(* check for '*' (ignore argument) *)
INC(i);
IF edG.Arg[0][i] = '*' THEN RETURN END;
(* calculate maximal width of string *)
maxWidth := 0;
WHILE (i < fmtLen) AND
(edG.Arg[0][i] >= '0') AND
(edG.Arg[0][i] <= '9') DO
maxWidth := maxWidth * 10 + ORD(edG.Arg[0][i])-ORD('0');
INC(i);
END; (* WHILE *)
IF i = fmtLen THEN
BadArgument; RETURN;
END;
IF maxWidth = 0 THEN maxWidth := edG.MaxLineLength-1 END;
(* is conversion-specifier 's' or '[..]' ? *)
IF edG.Arg[0][i] = 's' THEN
allAllowed := TRUE;
ELSIF edG.Arg[0][i] = '[' THEN
allAllowed := FALSE;
negAllowed := FALSE;
(* check for negation flags '~' and '^' *)
INC(i);
IF (edG.Arg[0][i] = '~') OR (edG.Arg[0][i] = '^') THEN
negAllowed := TRUE;
INC(i);
END; (* IF *)
j := 0;
allowedChars := "";
WHILE (i < fmtLen) AND
(j < (StrLen-1)) AND
(edG.Arg[0][i] # ']') DO
allowedChars[j] := edG.Arg[0][i];
INC(i);
INC(j);
END; (* WHILE *)
allowedChars[j] := 0X;
IF edG.Arg[0][i] # ']' THEN
BadArgument; RETURN;
END;
ELSE
BadArgument; RETURN;
END; (* IF *)
(* scan argument string *)
(* skip leading blanks in argStr *)
i := 0;
WHILE (i < argLen) AND (argStr[i] = ' ') DO
INC(i); END;
j := 0;
WHILE (i < argLen) AND
(j < maxWidth) AND
IsAllowed(argStr[i]) DO
INC(i);
INC(j);
END; (* WHILE *)
ol.New(edG.ScanStr,j+1);
IF edG.ScanStr=NIL THEN
INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
RETURN;
END;
e.CopyMem(edG.LineBuffer[edG.Text.pos],edG.ScanStr^,j);
edG.ScanStr[j] := 0X;
edL.Title(edG.ScanStr^); edG.Rc := edE.cmdValid2;
END doScanf;
(*-------------------------------------------------------------------------*)
PROCEDURE ReleaseVar(var: lst.NodePtr);
BEGIN
lst.Remove(VarList,var);
DISPOSE(var(Variable).string);
(*DISPOSE(var(Variable).name); wird mit var alocciert *)
DISPOSE(var);
END ReleaseVar;
PROCEDURE doSet*;
VAR
var: lst.NodePtr;
len: INTEGER;
PROCEDURE SetString;
BEGIN
len := str.Length(edG.Arg[1]^)+1;
ol.New(var(Variable).string,len);
IF var(Variable).string = NIL THEN
edG.Rc := edE.cmdSevere; INCL(edG.Status,edG.memoryFail);
ReleaseVar(var);
RETURN;
END;
e.CopyMem(edG.Arg[1]^,var(Variable).string^,len);
END SetString;
BEGIN
var := VarList.head;
WHILE var # NIL DO
IF var(Variable).name^ = edG.Arg[0]^ THEN
DISPOSE(var(Variable).string);
SetString;
RETURN;
END;
var := var.next;
END;
len := str.Length(edG.Arg[0]^)+1;
ol.New(var,sys.SIZE(Variable)+len);
IF var = NIL THEN
edG.Rc := edE.cmdSevere; INCL(edG.Status,edG.memoryFail);
RETURN;
END;
(* $TypeChk- *)
sys.INIT(var(Variable)); (* $TypeChk= *)
var(Variable).name := sys.VAL(LONGINT,var)+sys.SIZE(Variable);
e.CopyMem(edG.Arg[0]^,var(Variable).name^,len);
lst.AddTail(VarList,var);
SetString;
END doSet;
PROCEDURE doSetEnv*;
BEGIN
IF NOT sl.SetDEnv(edG.Arg[0]^,edG.Arg[1]^) THEN
edG.Rc := edE.cmdSevere;
END;
END doSetEnv;
PROCEDURE doUnsetEnv*;
BEGIN
IF NOT sl.UnSetDEnv(edG.Arg[0]^) THEN
edG.Rc := edE.cmdSevere;
END;
END doUnsetEnv;
PROCEDURE doUnset*;
VAR
var: lst.NodePtr;
len: INTEGER;
BEGIN
var := VarList.head;
WHILE var # NIL DO
IF var(Variable).name^ = edG.Arg[0]^ THEN
ReleaseVar(var);
RETURN;
END;
var := var.next;
END;
END doUnset;
PROCEDURE FreeVars;
VAR
var: lst.NodePtr;
BEGIN
WHILE VarList.head#NIL DO
var := VarList.head;
VarList.head := var.next;
ReleaseVar(var);
END;
END FreeVars;
(* search order: (1) intern variables, (2) ENV:, (3) key-macros *)
PROCEDURE GetVar*(find: edG.StringPtr): edG.StringPtr;
VAR
var: lst.NodePtr;
string, string2: edG.StringPtr;
len: INTEGER;
BEGIN
IF find^ = "findstr" THEN RETURN edG.FindStr;
ELSIF find^ = "repstr" THEN RETURN edG.ReplaceStr;
ELSIF find^ = "scanf" THEN RETURN edG.ScanStr;
ELSIF find^ = "filename" THEN RETURN sys.ADR(edG.Text.name);
ELSIF find^ = "rexxport" THEN RETURN sys.ADR(edG.AEdrxPort);
ELSIF find^ = "colno" THEN
IF cv.IntToString(LONG(edG.Text.pos+1),VarBuffer,12) THEN END;
RETURN sys.ADR(VarBuffer);
ELSIF find^ = "lineno" THEN
IF cv.IntToString(edG.Text.line+1,VarBuffer,12) THEN END;
RETURN sys.ADR(VarBuffer);
END;
var := VarList.head;
WHILE var # NIL DO
IF var(Variable).name^ = find^ THEN
RETURN var(Variable).string; END;
var := var.next;
END;
string2 := sl.GetDEnv(find^);
IF string2 # NIL THEN
(*string := edL.CopyString(string2);
DISPOSE(string2); (* _muß_ DISPOSE sein, wg. Environment.mod *)*)
INCL(edG.Status,edG.disposeString);
RETURN string2;
END;
string2 := edK.KeySpectroMacro(find);
IF string2 = NIL THEN string2 := eMn.MenuToMacro(find); END;
RETURN string2;
END GetVar;
(*-----------------------------------------------------------------------*)
PROCEDURE doFindStr*;
VAR
sp: POINTER TO edG.StringPtr;
len: INTEGER;
BEGIN
IF replace IN edG.ArgSet THEN sp := sys.ADR(edG.ReplaceStr);
ELSE sp := sys.ADR(edG.FindStr); END;
DISPOSE(sp^);
sp^ := edL.CopyString(edG.Arg[0]);
END doFindStr;
(*-----------------------------------------------------------------------*)
PROCEDURE Next{"FindNext"}(VAR findStruct{8}:FindReplaceStruct): LONGINT;
PROCEDURE Prev{"FindPrev"}(VAR findStruct{8}:FindReplaceStruct): LONGINT;
PROCEDURE Replace;
VAR
Rlen,Flen: INTEGER;
BEGIN
Rlen := str.Length(edG.ReplaceStr^);
Flen := str.Length(edG.FindStr^);
IF NOT(edG.LineBufferLen+Rlen-Flen<edG.MaxLineLength) THEN
edG.Rc := edE.cmdError; edL.Title(ReplaceLineTooLong); RETURN;
END;
str.Delete(edG.LineBuffer,edG.Text.pos,Flen);
str.Insert(edG.LineBuffer,edG.Text.pos,edG.ReplaceStr^);
INC(edG.Text.pos,Rlen);
edD.PutBackLine;
edD.TextRedisplayCurrentLine;
END Replace;
PROCEDURE doFind*;
VAR
LineChg: LONGINT;
FindData: FindReplaceStruct;
BEGIN
edD.PutBackLine;
IF NOT (oldStrings IN edG.ArgSet) THEN
DISPOSE(edG.FindStr);
edG.FindStr := edL.CopyString(edG.Arg[0]);
IF replace IN edG.ArgSet THEN
DISPOSE(edG.ReplaceStr);
edG.ReplaceStr := edL.CopyString(edG.Arg[1]);
IF edG.multiMode IN edG.Status THEN EXCL(edG.ArgSet,replace); END;
END;
IF edG.memoryFail IN edG.Status THEN RETURN; END;
END;
IF edG.FindStr = NIL THEN
edG.Rc := edE.cmdError; edL.Title(NoFindPattern); RETURN; END;
IF (replace IN edG.ArgSet) AND (edG.ReplaceStr = NIL) THEN
edG.Rc := edE.cmdError; edL.Title(NoReplacePattern); RETURN; END;
FindData.findStr := edG.FindStr; FindData.flen := str.Length(edG.FindStr^);
FindData.line := edG.Text.actLinePtr; FindData.pos := edG.Text.pos+1;
LOOP
IF previous IN edG.ArgSet THEN LineChg := Prev(FindData);
ELSE LineChg := Next(FindData); END;
IF (LineChg < 0) THEN
edG.Rc := edE.cmdFailed; edL.Title(PatternNotFound);
RETURN;
END;
edG.Text.actLinePtr := FindData.line; edG.Text.pos := FindData.pos;
IF previous IN edG.ArgSet THEN DEC(edG.Text.line,LineChg);
ELSE INC(edG.Text.line,LineChg); END;
edD.TextLoad;
edD.TextSync;
IF replace IN edG.ArgSet THEN
Replace;
ELSIF edG.multiMode IN edG.Status THEN
edL.Title(ReplaceQuestion); edG.Rc := edE.cmdValid2;
END;
IF ~((edG.multiMode IN edG.Status) & (replace IN edG.ArgSet))
OR (edG.Rc >= edE.AbortLevel) THEN
EXIT; END;
IF edL.BreakCheck() THEN edG.Rc := edE.cmdFailed; EXIT; END;
INC(FindData.pos,str.Length(edG.ReplaceStr^));
END;
END doFind;
(*-----------------------------------------------------------------------*)
(**** multi-replace ***)
PROCEDURE doMultiReplace*;
BEGIN
INCL(edG.Status,edG.multiMode);
doFind;
END doMultiReplace;
PROCEDURE MultiReplace*(IMsg: I.IntuiMessagePtr);
VAR
Buffer: ARRAY 2 OF CHAR;
Blen: INTEGER;
BEGIN
Blen := SHORT(sl.DeadKeyConvert(IMsg,Buffer,2,NIL));
IF Blen = 1 THEN
CASE Buffer[0] OF
"a": Replace;
IF edG.Rc < edE.AbortLevel THEN
edG.ArgSet := {replace,oldStrings};
doFind;
EXCL(edG.Status,edG.multiMode);
END;|
"y": Replace;
edG.ArgSet := {oldStrings};
doFind;|
"n": edG.ArgSet := {oldStrings};
doFind;|
"q",03X: (* Ctrl-C *)
EXCL(edG.Status,edG.multiMode);
edG.Rc := edE.cmdValid1; (* ob das so sinnvoll ist? *)
edL.WindowTitle;
RETURN;
ELSE
END;
END;
IF edG.Rc >= edE.AbortLevel THEN EXCL(edG.Status,edG.multiMode);
ELSIF edG.multiMode IN edG.Status THEN edL.Title(ReplaceQuestion); END;
END MultiReplace;
(*-------------------------------------------------------------------------*)
PROCEDURE doNewWindow*;
VAR
newText: edG.TextHeaderPtr;
nw: I.NewWindow;
BEGIN
nw := edG.StdWindow;
e.CopyMemQuick(edG.Config.edges,nw.leftEdge,sys.SIZE(edG.Config.edges));
IF edG.TempHeight#0 THEN
nw.height := edG.TempHeight; edG.TempHeight := 0;
END;
IF edG.TempWidth #0 THEN
nw.width := edG.TempWidth; edG.TempWidth := 0;
END;
IF edG.Screen # NIL THEN
nw.screen := edG.Screen;
nw.type := I.customScreen;
END;
newText := edL.TextInit(nw);
IF newText=NIL THEN
INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
RETURN;
END;
edD.SwitchEdit(newText);
END doNewWindow;
(* set LeftEdge/TopEdge/Width/Height/tempWidth/tempHeight *)
PROCEDURE doWinEdges*;
VAR
ip: POINTER TO INTEGER;
long: LONGINT;
BEGIN
IF temp IN edG.ArgSet THEN
IF height IN edG.ArgSet THEN ip := sys.ADR(edG.TempHeight);
ELSE ip := sys.ADR(edG.TempWidth); END;
ELSE
IF (leftEdge-edG.ArgSet={}) THEN ip := sys.ADR(edG.Config.edges.left);
ELSIF top IN edG.ArgSet THEN ip := sys.ADR(edG.Config.edges.top);
ELSIF height IN edG.ArgSet THEN ip := sys.ADR(edG.Config.edges.height);
ELSE ip := sys.ADR(edG.Config.edges.width); END;
END;
IF edL.StrToInt(edG.Arg[0],long) AND (long < MAX(INTEGER)) THEN
ip^ := ABS(SHORT(long));
ELSE
edL.Title(edG.BadArgument); edG.Rc := edE.cmdError;
END;
END doWinEdges;
PROCEDURE doResize*;
VAR
Win: I.WindowPtr;
cols, rows: LONGINT;
width, height: INTEGER;
BEGIN
IF NOT (edL.StrToInt(edG.Arg[0],cols))
OR NOT (edL.StrToInt(edG.Arg[1],rows)) THEN
edL.Title(edG.BadArgument); edG.Rc := edE.cmdError;
END;
Win := edG.Text.window;
width := (SHORT(cols)*Win.rPort.font.xSize)+Win.borderLeft+Win.borderRight;
height:= (SHORT(rows)*Win.rPort.font.ySize)+Win.borderTop+Win.borderBottom;
IF (width < 16) OR (height < 16)
OR (width > Win.wScreen.width - Win.leftEdge)
OR (height > Win.wScreen.height - Win.topEdge) THEN
edL.Title(WindowTooBig); edG.Rc := edE.cmdError;
RETURN;
END;
I.SizeWindow(Win,width-Win.width, height-Win.height);
edD.SetWindowParams;
d.Delay(50*2); (* wait 2 seconds *)
END doResize;
(*-------------------------------------------------------------------------*)
PROCEDURE doMyPri*;
VAR
long: LONGINT;
BEGIN
IF edL.StrToInt(edG.Arg[0],long) AND (long<=MAX(SHORTINT))
AND (long>=MIN(SHORTINT)) THEN
IF e.SetTaskPri(e.FindTask(NIL),SHORT(SHORT(long))) = 0 THEN END;
ELSE
edL.Title(edG.BadArgument); edG.Rc := edE.cmdError;
END;
END doMyPri;
PROCEDURE doExecute*;
VAR
OldLock: d.FileLockPtr;
BEGIN
OldLock := d.CurrentDir(edG.Text.dirLock);
IF NOT d.Execute(edG.Arg[0]^,NIL,NIL) THEN
edG.Rc := edE.cmdFailed; edL.Title(ExecuteFailed); END;
OldLock := d.CurrentDir(OldLock);
END doExecute;
(*-------------------------------------------------------------------------*)
BEGIN
lst.Init(VarList);
edG.FindStr := NIL; edG.ReplaceStr := NIL; edG.ScanStr := NIL;
edG.Screen := NIL;
CLOSE
IF edG.Screen # NIL THEN I.OldCloseScreen(edG.Screen); END;
FreeVars;
END EdCmd2.